package com.lottery.game.controller.v2.bet;

import com.lottery.game.annotation.Current;
import com.lottery.game.common.Response;
import com.lottery.game.common.constants.GlobalLotteryConstants;
import com.lottery.game.constants.RespErrorCodes;
import com.lottery.game.controller.v2.bet.request.UserBetCancelRequest;
import com.lottery.game.core.model.dto.UserToken;
import com.lottery.game.core.modules.entity.app.AddBetRequest;
import com.lottery.game.core.modules.entity.user.GameBets;
import com.lottery.game.core.modules.entity.user.GameIssue;
import com.lottery.game.core.modules.entity.user.HuiShui;
import com.lottery.game.core.modules.entity.user.UserBlncDetail;
import com.lottery.game.core.modules.service.app.BetService;
import com.lottery.game.core.modules.service.app.GameBetService;
import com.lottery.game.core.utils.BetUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import springfox.documentation.annotations.ApiIgnore;

@Slf4j
@RestController
@RequestMapping(value = "/api/v2/user/bet")
@Api(tags = "APP-用户下注接口")
public class BetController {

    @Autowired
    private GameBetService gameBetsService;

    @Autowired
    private BetService betService;

    /**
     * 用户下注
     * @param userToken
     * @param
     * @return
     */
    @SuppressWarnings("unchecked")
    @ApiOperation(value = "用户下注", notes = "下注不能低于10    用户下注-需要ticket(登陆获取),[注意可以下注多次,betStr字段可以为(da,dan),point是每注的单价,totleAmt是总价]" +
            "\nheader :  ticket"+
            "\nbody :\n{\"betList\": \"[da,lanbo]\",\n" + "    \"gameId\": \"0dc8c24b01944ea595296a0e8f31df2c\",\n" + "    \"pointList\": [10,20],\n" + "    \"roomId\": 26,\n" + "    \"totleAmt\": 10\n" + "}"
           , httpMethod = "POST")
    @ApiResponses({
          @ApiResponse(code = -200, message = "-200 游戏期次已过期，会返回一个新的游戏期次，可以更新到本地的期次信息。再下注提交对应的id信息作为gameid", response=Response.class)
    })
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ticket", value = "令牌ticket", dataType = "String", paramType = "header",required = true),
    })
    @PostMapping(value = "/", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public Response<String> userBet(@ApiIgnore @Current UserToken userToken, @RequestBody AddBetRequest param) {

        if (CollectionUtils.isEmpty(param.getBetList())) {
            return Response.buildError(RespErrorCodes.PARAM_BET_EMPTY_ERROR.getErrorMsg());
        }
        if (BetUtils.isBlank(param.getTotleAmt()) || CollectionUtils.isEmpty(param.getPointList())) {
            return Response.buildError(RespErrorCodes.PARAM_TOTAL_AMOUNT_EMPTY_ERROR.getErrorMsg());
        }
        if (StringUtils.isEmpty(userToken.getId())) {
            return Response.buildError(RespErrorCodes.PARAM_USER_ID_EMPTY_ERROR.getErrorMsg());
        }
        if (StringUtils.isEmpty(param.getRoomId())) {
            return Response.buildError(RespErrorCodes.PARAM_ROOM_ID_EMPTY_ERROR.getErrorMsg());
        }
        if (StringUtils.isEmpty(param.getGameId())) {
            return Response.buildError(RespErrorCodes.PARAM_GAME_ID_EMPTY_ERROR.getErrorMsg());
        }
        try {
            GameIssue gameIssue = new GameIssue();
            gameIssue.setId(param.getGameId());
            gameIssue.setRoomId(param.getRoomId());
            GameIssue tmpIssue = betService.checkGameIssue(gameIssue);
            // 如果检查获取的tmp期次和传入参数相同，则进行新增。否则返回最新期次
            if (param.getGameId().equals(tmpIssue.getId())) {
                //设置期数时间
                param.setGameIssue(StringUtils.isEmpty(tmpIssue.getIssue())==true?"":tmpIssue.getIssue());
                int i = gameBetsService.addGameBets(param,userToken.getId());
                if (i == GlobalLotteryConstants.RES_ERROR){
                    return Response.buildError("余额不足");
                }
                return Response.build("下注成功");
            } else {
                return Response.build(GlobalLotteryConstants.RES_ERROR_CODE_ONE,
                        GlobalLotteryConstants.RES_ERROR_STR_ONE,tmpIssue,Boolean.TRUE);
            }
        } catch (Exception e) {
            log.error(RespErrorCodes.UNKNOWN_ERROR.errorCode(), e);
            return Response.buildError(RespErrorCodes.UNKNOWN_ERROR.getErrorMsg());
        }
    }

    /**
     * 用户取消下注
     * @param userToken
     * @param request
     * @return
     */
    @SuppressWarnings("unchecked")
    @ApiOperation(value = "用户取消下注", notes = "用户取消下注-需要ticket" +
            "\n \"header :  ticket\""+
            "\n body参数 :{\n" + "\"gameBetId\": \"4f47daab5c544329a2a6fe11e2e509cf\",\n" + "    \"gameId\": \"f0dfe614bd134a22ba0dc40a6e4e42cd\",\n" + "    \"roomId\": 27\n" + "}",
            httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ticket", value = "令牌ticket", dataType = "String", paramType = "header",required = true),
    })
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "", response = Response.class) }
            )
    @PostMapping(value = "/cancel", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public Response<String> userBetCancel(@ApiIgnore @Current UserToken userToken,
                                         @RequestBody UserBetCancelRequest request) {
        try {
            int gamebetSize = request.getGameBetIdList().size();
            if (gamebetSize != 0) {
                int n = 0;
                for (int i = 0; i < gamebetSize; i++) {
                    GameBets gameBets = new GameBets();
                    gameBets.setRoomId(request.getRoomId());
                    gameBets.setGameId(request.getGameId());
                    gameBets.setId(request.getGameBetIdList().get(i));
                    int num = gameBetsService.deleteGameBets(gameBets);
                    if (num == GlobalLotteryConstants.RES_ERROR) {
                        return Response.buildError("已取消下注，请不要重复操作");
                    } else if (num == GlobalLotteryConstants.RES_ERROR_TWO) {
                        return Response.buildError("下注信息获取异常，只能取消一条");
                    }
                    n += num;
                }
                if (n == gamebetSize) {
                    return Response.buildSuccess("取消下注成功");
                } else {
                    return Response.buildError(RespErrorCodes.BET_CANCEL_FAIL_ERROR.getErrorMsg());
                }
            }else {
                return Response.buildError("参数不符合规范");
            }
        } catch (Exception e) {
            log.error("删除用户下注发生错误", e);
            return Response.buildError(RespErrorCodes.UNKNOWN_ERROR.getErrorMsg());
        }

    }

      /*  GameBets gameBets = new GameBets();
        gameBets.setRoomId(request.getRoomId());
        gameBets.setGameId(request.getGameId());
        gameBets.setId(request.getGameBetId());

        if (StringUtils.isEmpty(gameBets.getRoomId())) {
            return Response.buildError(RespErrorCodes.TOKEN_INVALID_ERROR.getErrorMsg());
        }
        gameBets.setGameUserId(userToken.getId());
        if (StringUtils.isEmpty(gameBets.getGameId())) {
            return Response.buildError(RespErrorCodes.PARAM_GAME_ID_EMPTY_ERROR.getErrorMsg());
        }
        try {
            int n = gameBetsService.deleteGameBets(gameBets);
            if (n == 1) {
                return Response.buildSuccess("取消下注成功");
            }else if (n==GlobalLotteryConstants.RES_ERROR){
                return Response.buildError("已取消下注，请不要重复操作");
            }else if (n==GlobalLotteryConstants.RES_ERROR_TWO){
                return Response.buildError("下注信息获取异常，只能取消一条");
            }else {
                return Response.buildError(RespErrorCodes.BET_CANCEL_FAIL_ERROR.getErrorMsg());
            }
        } catch (Exception e) {
            log.error("删除用户下注发生错误", e);
            return Response.buildError(RespErrorCodes.UNKNOWN_ERROR.getErrorMsg());
        }
    }*/

    /**
     * 用户下注列表
     * @param userToken
     * @param roomId
     * @param gameId
     * @param pageNo
     * @param pageSize
     * @param startDate
     * @param endDate
     * @return
     */
    @SuppressWarnings("unchecked")
    @ApiOperation(value = "用户下注列表", notes = "获取用户下注列表", httpMethod = "GET")
    @ApiResponses(value = { @ApiResponse(code = 0, message = "", response = Response.class) })
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ticket", value = "令牌ticket", dataType = "String", paramType = "header",required = true),
            @ApiImplicitParam(name = "roomId", value = "房间Id", dataType = "String",required = true,example = "26"),
            @ApiImplicitParam(name = "gameId", value = "游戏Id", dataType = "String",required = true,example = "0dc8c24b01944ea595296a0e8f31df2c"),
            @ApiImplicitParam(name = "pageNo", value = "页数", dataType = "Integer",required = true,example = "1"),
            @ApiImplicitParam(name = "pageSize", value = "每页记录数", dataType = "Integer",required = true,example = "10"),
            @ApiImplicitParam(name = "startDate", value = "开始日期", dataType = "String",required = true,example = "2017-10-01"),
            @ApiImplicitParam(name = "endDate", value = "结束日期", dataType = "String",required = true,example = "2019-04-14")
    })
    @GetMapping(value = "/list", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public Response<List<GameBets>> userBetList(
           @ApiIgnore @Current UserToken userToken,
           @RequestParam("roomId") String roomId, @RequestParam("gameId") String gameId,
           @RequestParam("pageNo") Integer pageNo, @RequestParam("pageSize") Integer pageSize,
           @RequestParam("startDate") String startDate, @RequestParam("endDate") String endDate) {

        if (pageNo == null || pageNo == 0 || pageSize == null || pageSize == 0) {

            return Response.buildError(RespErrorCodes.PARAM_PAGE_INVALID_ERROR.getErrorMsg());
        }

        int start = (pageNo - 1) * pageSize;
        int size = pageSize;
        try {
            List<GameBets> list = gameBetsService.queryGameBetsForRoom(userToken.getId(), roomId, gameId, start, size, startDate,
                    endDate);
            return Response.build(list);

        } catch (Exception e) {
            log.error("获取用户下注列表发生错误", e);
            return Response.buildError(RespErrorCodes.UNKNOWN_ERROR.getErrorMsg());
        }
    }

    /**
     * 获取用户下注总额
     * @param userToken
     * @param roomNumber
     * @param startDate
     * @param endDate
     * @return
     */
    @SuppressWarnings("unchecked")
    @ApiOperation(value = "用户下注总额", notes = "获取用户下注总额-需要ticket", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ticket", value = "令牌ticket", dataType = "String", paramType = "header",example = "eyJpZCI6IjMxNjNjYzY3Mzg0ZDRkNWViNmFmZThlMGZlMDJiYzlhIiwibG9naW5UaW1lIjoxNTU1MzExNTc2MzI4LCJwaG9uZSI6IjE1MzQ4MzA0MjI4Iiwic2lnbiI6IjI0Y2YyNWM1ZmE5ODcwZGYxNGVhZGI3OTgzNzhhMzg0IiwidXNlcm5hbWUiOiIxNTM0ODMwNDIyOCJ9",required = true),
            @ApiImplicitParam(name = "roomNumber", value = "房间号", dataType = "Integer",example = "26",required = true),
            @ApiImplicitParam(name = "startDate", value = "开始日期", dataType = "String",example = "2017-10-01",required = true),
            @ApiImplicitParam(name = "endDate", value = "结束日期", dataType = "String",example = "2017-10-01",required = true) })
    @GetMapping(value = "/total", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public Response<Map<String, Object>> userBetSum(@ApiIgnore @Current UserToken userToken,
                                                                   @RequestParam("roomNumber") String roomNumber, @RequestParam("startDate") String startDate,
                                                                   @RequestParam("endDate") String endDate) {
        try {
            Map<String, Object> map = gameBetsService.queryUserBetSum(userToken.getId(), roomNumber, startDate, endDate);

            return Response.build(map);
        } catch (Exception e) {
            log.error("获取用户下注总额发生错误", e);
            return Response.buildError(RespErrorCodes.UNKNOWN_ERROR.getErrorMsg());
        }
    }

    /**
     * 获取用户余额变化明细记录 给客户端使用，下注，下注取消，奖金汇总为 下注一种类型
     * @param userToken
     * @param pageNo
     * @param pageSize
     * @param startDate
     * @param endDate
     * @param type
     * @return
     */
    @SuppressWarnings("unchecked")
    @ApiOperation(value = "用户余额变化明细记录", notes = "需要ticket-获取用户余额变化明细记录，给客户端使用，下注，下注取消，奖金汇总为 下注一种类型", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ticket", value = "令牌ticket", dataType = "String", paramType = "header",required = true),
            @ApiImplicitParam(name = "pageNo", value = "页数", dataType = "Integer",required = true,example = "1"),
            @ApiImplicitParam(name = "pageSize", value = "每页记录数", dataType = "Integer",required = true,example = "10"),
            @ApiImplicitParam(name = "startDate", value = "开始日期", dataType = "String",required = true, example="2017-10-01"),
            @ApiImplicitParam(name = "endDate", value = "结束日期", dataType = "String",required = true ,example = "2019-04-14"),
            @ApiImplicitParam(name = "type", value = "类型(inOut:出入相关的,充值提现;betAll:下注相关的,下注下注取消奖金,其他)", dataType = "String",required = true ,example = "betAll") })
    @GetMapping(value = "/finance/logs", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public Response<List<UserBlncDetail>> getUserMoneyChangeList(
            @ApiIgnore @Current UserToken userToken,
            @RequestParam("pageNo") Integer pageNo, @RequestParam("pageSize") Integer pageSize,
            @RequestParam("startDate") String startDate, @RequestParam("endDate") String endDate,
            @RequestParam("type") String type) {
        if (pageNo == null || pageSize == null || pageNo == 0 || pageSize == 0) {
            return Response.buildError(RespErrorCodes.PARAM_PAGE_INVALID_ERROR.getErrorMsg());
        }

        try {
            int start = (pageNo - 1) * pageSize;
            List<UserBlncDetail> list = betService.queryUserBlncDetailByType(userToken.getId(), start, pageSize, startDate,
                    endDate, type);

            return Response.build(list);
        } catch (Exception e) {
            log.error("获取用户余额变化明细记录发生错误", e);
            return Response.buildError(RespErrorCodes.UNKNOWN_ERROR.getErrorMsg());
        }
    }

    /**
     * 回水接口 获取用户的各个房间的回水记录
     * @param userToken
     * @param roomNumber
     * @param pageNo
     * @param pageSize
     * @return
     */
    @SuppressWarnings("unchecked")
    @ApiOperation(value = "回水接口", notes = "需要ticket-获取用户的各个房间的回水记录", httpMethod = "GET")
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "", response = Response.class) }
            )
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ticket", value = "令牌ticket", dataType = "String", paramType = "header",required = true),
            @ApiImplicitParam(name = "roomNumber", value = "用户id", dataType = "String",example = "26",required = true),
            @ApiImplicitParam(name = "pageNo", value = "页数", dataType = "Integer",example = "1",required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页记录数", dataType = "Integer",example = "10",required = true) })
    @RequestMapping(value = "/runback", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public Response<List<HuiShui>> queryHuiShui(
            @ApiIgnore @Current UserToken userToken,
            @RequestParam("roomNumber") String roomNumber,
            @RequestParam("pageNo") Integer pageNo,
            @RequestParam("pageSize") Integer pageSize) {
        if (pageNo == null || pageSize == null || pageNo == 0 || pageSize == 0) {
            return Response.buildError(RespErrorCodes.PARAM_PAGE_INVALID_ERROR.getErrorMsg());
        }
        try {
            int start = (pageNo - 1) * pageSize;
            List<HuiShui> list = betService.getHuiShui(userToken.getId(), roomNumber, start, pageSize);
            return Response.build(list);
        } catch (Exception e) {
            log.error("获取用户的各个房间的回水记录发生错误", e);
            return Response.buildError(RespErrorCodes.UNKNOWN_ERROR.getErrorMsg());
        }
    }
}
